﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using WebApplication3.Data;
using WebApplication3.Data.Entities;
using WebApplication3.Models;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace WebApplication3.Controllers
{
	public class AccountController : Controller
	{
		private readonly ApplicationDbContext myDataContext;
		private readonly UserManager<AppIdentityUser> userManager;
		private readonly RoleManager<AppIdentityRole> roleManager;
		private readonly SignInManager<AppIdentityUser> _signInManager;
		private readonly ILogger _logger;

		public AccountController(ApplicationDbContext myDataContext,
			UserManager<AppIdentityUser> userManager,
			RoleManager<AppIdentityRole> roleManager,
			SignInManager<AppIdentityUser> signInManager ,
			 ILoggerFactory loggerFactory
			 
			)
		{
			this.myDataContext = myDataContext;
			this.userManager = userManager;
			this.roleManager = roleManager;
			this._signInManager = signInManager;
			this._logger = loggerFactory.CreateLogger<AccountController>( );
		}
		public IActionResult Index()
		{
			return View();
		}
		[Route("login")]
		public async Task<IActionResult> LoginAsync(string code,string openid)
		{
			if (User.Identity.IsAuthenticated)
				return Ok();

			if (!string.IsNullOrWhiteSpace(openid))
			{
				 
				var user = myDataContext.Users.SingleOrDefault
					(s=>s.OpenId==openid);

				 

				//var user = myDataContext.Users.SingleOrDefault(s => s.OpenId == openid);
				var results = await _signInManager.PasswordSignInAsync(
					user.Email,
					ConstData. UserDefaultPwd,
					true,
					lockoutOnFailure: false);
				if(results.Succeeded)
				return Ok();
			}

			var appid = ConstData.WXAppId;
			var appSecret = ConstData.WXAppSecret;
			var jsCode = code;
			string url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={appSecret}&js_code={jsCode}&grant_type=authorization_code";


			var result = await HttpHelper.PostAsync<WXLoginResult>(url, "");

			if (!string.IsNullOrWhiteSpace(result?.session_key))
			{
				AppIdentityUser user=null;
				if (!myDataContext.Users.Any(s => s.OpenId == result.openid))
				{
					var addUserResult=await userManager.CreateAsync(new AppIdentityUser
					{
						CreatedAt = DateTime.Now,
						UpdatedAt = DateTime.Now,
						Mobile = "1",
						OpenId = result.openid,
						Sex = "1",
						ShopNo = "2",
						UserData = "",
						UserName = result.openid, Email= result.openid+"@wx.com",
						  CNName=""
						  

					}, ConstData.UserDefaultPwd);
					if (addUserResult.Succeeded)
					{
						user= GetByOpenId(result.openid);

						await userManager.AddToRoleAsync(user, "Customer");
					} 
				}
				else
				{
					user = myDataContext.Users.SingleOrDefault(s => s.OpenId == result.openid);
				}


				myDataContext.LoginSeesions.Add(new Data.Entities.LoginSeesion
				{
					OpenId = result.openid,
					SessionKey = result.session_key
				});
				int n = myDataContext.SaveChanges();

				var siginResult=await _signInManager.PasswordSignInAsync(user.UserName,ConstData.UserDefaultPwd, false,false);

				if (siginResult.Succeeded)
				{
					return Json( new { openid = result.openid });
				}

			}
			return Unauthorized();
		}

		#region snippet_login
		[HttpGet]
		public IActionResult Login()
		{
			return View();
		}
		//
		// POST: /Account/Login
		[HttpPost]
		[AllowAnonymous]
		//[ValidateAntiForgeryToken]
		public async Task<IActionResult> Login( LoginViewModel model, string returnUrl = null)
		{
			ViewData["ReturnUrl"] = returnUrl;
			if (ModelState.IsValid)
			{
				// This doesn't count login failures towards account lockout
				// To enable password failures to trigger account lockout, set lockoutOnFailure: true
				var result = await _signInManager.PasswordSignInAsync(model.UserName,
					model.Password, model.RememberMe, lockoutOnFailure: false);
				if (result.Succeeded)
				{
					_logger.LogInformation(1, "User logged in.");
					//this.RedirectToLocal(returnUrl);
					return Ok(new { code=0, data=model.UserName});
				}
				 
				if (result.IsLockedOut)
				{
					_logger.LogWarning(2, "User account locked out.");
					return Ok(new { code = 1, data = "User account locked out." });
				}
				else
				{
					ModelState.AddModelError(string.Empty, "Invalid login attempt.");
					return Ok(new { code = 2, data = "Invalid login attempt." });
				}
			}

			// If we got this far, something failed, redisplay form
			return Ok(new { code = 3, data = "Unauthorized" });
			//return Unauthorized();
		}
		#endregion

		private AppIdentityUser GetByOpenId(string openid) {
			var user = myDataContext.Users.SingleOrDefault
					(s => s.OpenId == openid);

			return user;
		}


		public IActionResult AccessDenied() {
			return View();

		}

		private IActionResult RedirectToLocal(string returnUrl)
		{
			if (Url.IsLocalUrl(returnUrl))
			{
				return Redirect(returnUrl);
			}
			else
			{
				return RedirectToAction(nameof(HomeController.Index), "Home");
			}
		}
	}
}
